package impl

import (
	"context"

	"gitee.com/lishixi/gops/vblog/apps/user"
	"github.com/infraboard/mcube/v2/ioc"
	"github.com/infraboard/mcube/v2/ioc/config/datasource"
	"golang.org/x/crypto/bcrypt"
)

var _ user.Service = (*ServiceImpl)(nil)

func init() {
	ioc.Controller().Registry(&ServiceImpl{})
}

func (*ServiceImpl) Name() string {
	return user.AppName
}

type ServiceImpl struct {
	// 这个对象实现了 ioc 的 object 接口
	ioc.ObjectImpl
}

// DescribeUser implements user.Service.
func (u *ServiceImpl) DescribeUser(ctx context.Context, in *user.DescribeUserStatusRequest) (*user.User, error) {
	query := datasource.DBFromCtx(ctx)
	switch in.DescribeBy {
	case user.DESCRIBE_BY_ID:
		query = query.Where("id = ?", in.Value)
	case user.DESCRIBE_BY_USERNAME:
		query = query.Where("user_name = ?", in.Value)
	}
	ins := &user.User{}
	if err := query.Take(ins).Error; err != nil {
		return nil, err
	}
	return ins, nil
}

// UpdateUserStatus implements user.Service.
func (u *ServiceImpl) UpdateUserStatus(context.Context, *user.UpdateUserStatusRequest) (*user.User, error) {
	panic("unimplemented")
}

// Registry implements user.UserService.
func (u *ServiceImpl) Registry(ctx context.Context, in *user.RegistryRequest) (*user.User, error) {

	ins, err := user.New(in)
	if err != nil {
		return nil, err
	}
	// 密码现在是明文保存，不安全
	// 加密：对称加密，非对称加密
	// 消息摘要(hash) 不可逆，hash 结果是固定的
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(in.Password), bcrypt.DefaultCost)
	if err != nil {
		return nil, err
	}
	ins.Password = string(hashPassword)

	if err := datasource.DBFromCtx(ctx).Save(ins).Error; err != nil {
		return nil, err
	}

	return ins, nil
}

// ResetPassword implements user.UserService.
func (u *ServiceImpl) ResetPassword(context.Context, *user.ResetPasswordRequest) error {
	panic("unimplemented")
}

// UnRegistry implements user.UserService.
func (u *ServiceImpl) UnRegistry(context.Context, *user.UnRegistryRequest) {
	panic("unimplemented")
}

// UpdatePassword implements user.UserService.
func (u *ServiceImpl) UpdatePassword(ctx context.Context, in *user.UpdatePasswordRequest) (*user.User, error) {
	// 查询用户
	ins, err := u.DescribeUser(ctx, &user.DescribeUserStatusRequest{
		DescribeBy: user.DESCRIBE_BY_USERNAME,
		Value:      in.UserName,
	})
	if err != nil {
		return nil, err
	}
	// 校验老密码
	if err := ins.CheckPassword(in.OldPassword); err != nil {
		return nil, err
	}
	// 判断新老密码是否一致？ TODO
	// 更新密码
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(in.NewPassword), bcrypt.DefaultCost)
	if err != nil {
		return nil, err
	}
	ins.Password = string(hashPassword)
	// 保存更新后的结果
	if err := datasource.DBFromCtx(ctx).Where("user_name = ?", in.UserName).Take(&user.User{}).Updates(ins).Error; err != nil {
		return nil, err
	}
	return ins, nil
}

// UpdateProfile implements user.UserService.
func (u *ServiceImpl) UpdateProfile(context.Context, *user.UpdateProfileRequest) (*user.User, error) {
	panic("unimplemented")
}
